﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Web.Ajax.Reflection
{
	public class MemberInfo
	{
		public string Name;
		public System.Type ContainerType;
		public System.Type MemberType;
		
		public MemberInfo(string name, System.Type containerType)
		{
			Name=name;
			ContainerType = containerType;
		}

		private bool reflectionInfoRetrieved;
		private FieldInfo fieldInfo;
		private PropertyInfo propertyInfo;

		public void GetReflectionInfo()
		{
			if (!reflectionInfoRetrieved && ContainerType != null)
			{
				fieldInfo = ContainerType.GetField(Name);
				if (fieldInfo == null)
					propertyInfo = ContainerType.GetProperty(Name);
				reflectionInfoRetrieved = true;
			}
		}

		public System.Type GetMemberType()
		{
			if (MemberType == null)
			{
				GetReflectionInfo();
				if (fieldInfo != null)
					return fieldInfo.FieldType;
				if (propertyInfo != null)
					return propertyInfo.PropertyType;
			}
			return MemberType;
		}

		public object GetValue(object container)
		{
			if (fieldInfo != null)
				return fieldInfo.GetValue(container);
			if (propertyInfo != null)
				return propertyInfo.GetValue(container, null);
			return null;
		}



	
		public static System.Reflection.MemberInfo GetMemberInfo(System.Type t, string name)
		{
			if (t == null || string.IsNullOrEmpty(name))
				return null;
			var fi = t.GetField(name);
			if (fi != null)
				return fi;
			var pi = t.GetProperty(name);
			if (pi != null)
				return pi;
			return null;
		}

		public static System.Type GetMemberInfoType(System.Reflection.MemberInfo mi)
		{
			if (mi == null)
				return null;
			if (mi is System.Reflection.FieldInfo)
				return (mi as FieldInfo).FieldType;
			if (mi is System.Reflection.PropertyInfo)
				return (mi as PropertyInfo).PropertyType;
			return null;
		}

		public static void SetMemberInfoValue(System.Reflection.MemberInfo mi, object obj, object value)
		{
			if (mi == null || obj == null)
				return;
			if (obj.GetType() != mi.ReflectedType)
				return;
			if (mi is System.Reflection.FieldInfo)
				(mi as FieldInfo).SetValue(obj, value);
			if (mi is System.Reflection.PropertyInfo)
				(mi as PropertyInfo).SetValue(obj, value, null);
		}
	}
}
